import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Calendar;
import java.util.Hashtable;

import javax.microedition.io.ConnectionNotFoundException;
import javax.microedition.io.StreamConnection;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.ItemCommandListener;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.TextField;
import javax.microedition.location.Criteria;
import javax.microedition.location.Location;
import javax.microedition.location.LocationListener;
import javax.microedition.location.LocationProvider;
import javax.microedition.location.QualifiedCoordinates;
import javax.microedition.midlet.MIDlet;

public class HelloWorldMidlet extends MIDlet implements CommandListener,
		MessageServiceDelegate {

	// Display
	private Display display;
	// Main form
	private Form form;
	// For the message
	private StringItem stringItem;
	private TextField textField1, textField2;
	// For the exit command
	private Command helpCommand;
	private Command callCommand;
	private Command startLoggingCommand;
	private Command activateAccelCommand;
	private Command exitCommand;

	// For GPS
	private Criteria criteria;
	private LocationProvider lp;
	private QualifiedCoordinates qc;
	private double lon, lat, alt;
	private int step;

	// For chatting
	private StreamConnection connection;
	//private DataInputStream din;
	//private DataOutputStream dout;
	private InputStream in;
	private OutputStream out;

	private class LocationUpdater implements LocationListener {

		public void locationUpdated(LocationProvider lp, Location loc) {

			qc = loc.getQualifiedCoordinates();

			if (qc != null) {
				// Use coordinate information
				lat = qc.getLatitude();
				lon = qc.getLongitude();
				// alt = qc.getAltitude();

				String response = null;
				try {
					response = Util.sendHttpGet("http://home.sumin.us:8000/labs/maps/data.php?cmd=add&lat="
							+ lat + "&lng=" + lon);
				} catch (IOException e) {
					stringItem.setText(e.toString());
				}

				stringItem.setText(step++ + ":\nlon=" + lon + "\nlat=" + lat
						+ "\nalt=" + alt + "\ntimestamp=" + loc.getTimestamp()
						+ "\nresponse=" + response);
			} else {
				stringItem.setText("Coordinate is null (" + step++ + ")");
			}
		}

		public void providerStateChanged(LocationProvider lp, int arg1) {
		}

	}

	private void startLocationService() {
		criteria = new Criteria();
		criteria.setHorizontalAccuracy(10);
		criteria.setVerticalAccuracy(100);
		criteria.setPreferredPowerConsumption(Criteria.POWER_USAGE_HIGH);
		try {
			lp = LocationProvider.getInstance(criteria);
			lp.setLocationListener(new LocationUpdater(), 6, 6, -1);
		} catch (Exception e) {
			form.append("Exception: " + e);
		}

	}

	private void startMessagingService() {
		try {
			messageReceived("Connecting to server...");
			//connection = (StreamConnection) Connector
			//		.open("socket://128.196.51.248:8099");
			
			//din = new DataInputStream(connection.openInputStream());
			//dout = new DataOutputStream(connection.openOutputStream());
//			in = connection.openInputStream();
//			out = connection.openOutputStream();
			// receiveMessage(String.format("CW: Connected to server %s\n",
			// socket
			// .getInetAddress()));

			new MessageServiceThread(this, in).start();
			// receiveMessage("CW: ClientWindowThread successfully launched");
		} catch (Exception e) {
			exceptionRaised(e);
		}

	}

	private void activateAcclerometer() {
	}

	public void commandAction(Command command, Displayable displayable) {
		if (displayable == form) {
			if (command == startLoggingCommand) {
				startLocationService();
			} else if (command == activateAccelCommand) {
				activateAcclerometer();
			} else if (command == exitCommand) {
				exitMIDlet();
			} else if (command == callCommand) {
				try {
					platformRequest("tel:+15204014667");
				} catch (ConnectionNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	public void startApp() {
		display = Display.getDisplay(this);

		startLoggingCommand = new Command("Start Logging", Command.ITEM, 11);
		activateAccelCommand = new Command("Activate Accelerometer",
				Command.ITEM, 12);
		callCommand = new Command("Call Sumin", Command.ITEM, 13);
		helpCommand = new Command("Help", Command.HELP, 3);
		exitCommand = new Command("Exit", Command.EXIT, 4);

		// Create form
		stringItem = new StringItem("Akshen", "");
		textField1 = new TextField(null, null, 10240, TextField.UNEDITABLE);
		textField1.setPreferredSize(320, 200);

		textField2 = new TextField(null, null, 1024, TextField.ANY);
		textField2.setPreferredSize(320, 20);
		textField2.setItemCommandListener(new ItemCommandListener() {
			public void commandAction(Command cmd, Item item) {
				TextField textField = (TextField) item;
				try {
					sendMessage(textField.getString());
					textField.setString("");
				} catch (IOException e) {
					messageReceived("IOException: " + e.toString());
				}
				catch (Exception e) {
					messageReceived("Exception: " + e.toString());
				}
			}
		});
		Command okCommand = new Command("Send", Command.ITEM, 1);
		textField2.addCommand(okCommand);
		textField2.addCommand(exitCommand);
		// textField2.setDefaultCommand(okCommand);

		form = new Form(null, new Item[] { stringItem, textField1, textField2 });
		display.setCurrent(form);
		form.setTitle("This is the title of form");

		startMessagingService();

		form.addCommand(startLoggingCommand);
		form.addCommand(activateAccelCommand);
		form.addCommand(callCommand);
		form.addCommand(helpCommand);
		form.addCommand(exitCommand);
		form.setCommandListener(this);

	}

	// Your MIDlet should not call pauseApp(), only system will call this
	// life-cycle method
	public void pauseApp() {
	}

	// Your MIDlet should not call destroyApp(), only system will call this
	// life-cycle method
	public void destroyApp(boolean unconditional) {
	}

	public void exitMIDlet() {
		display.setCurrent(null);
		notifyDestroyed();
	}

	public void messageReceived(String message) {
		Calendar cal = Calendar.getInstance();
		textField1.setString(textField1.getString() + "\n"
				+ cal.get(Calendar.HOUR) + ":" + cal.get(Calendar.MINUTE)
				+ ": " + message);
	}

	public void sendMessage(String message) throws IOException {
		//dout.write(message.getBytes());
		//dout.flush();
		//out.write(message.getBytes());
		//out.flush();
		Hashtable data = new Hashtable();
		data.put("text", message);
		Util.sendHttpPost("http://128.196.51.242/frontend/send.php", data);
	}

	public void exceptionRaised(Exception e) {
		Calendar cal = Calendar.getInstance();
		textField1.setString(textField1.getString() + "\n"
				+ cal.get(Calendar.HOUR) + ":" + cal.get(Calendar.MINUTE)
				+ ": " + e.toString());
	}

}